package cn.tedu.csmall.product.aspect;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

/**
 * 业务切入
 *
 * @author Chen
 * @since 2023/2/15 10:38:38
 */
@Slf4j
@Aspect
@Component
public class ServiceAspect {

    @Pointcut("execution(* cn.tedu.csmall.product.service.*.*(..))")
    private void pointCutMethod() {

    }

    @Around("pointCutMethod()")
    public Object timerAspect(ProceedingJoinPoint pjp) throws Throwable {
        String methodName = pjp.getSignature().getName();
        String typeName = pjp.getTarget().getClass().getName();
        Object[] args = pjp.getArgs();
        long start = System.currentTimeMillis();
        Object result = pjp.proceed();
        long end = System.currentTimeMillis();
        log.debug("【业务环绕通知】业务【{}】，执行方法【{}】，参数【{}】，耗时：{}ms", typeName, methodName, args, end - start);
        log.debug("【业务环绕通知】执行返回值：{}", result);
        return result;
    }

    @Before("pointCutMethod()")
    public void beforeAdvice() {
        log.debug("【业务前置通知】开始执行");
    }

    @AfterReturning(pointcut = "pointCutMethod()", returning = "result")
    public void afterReturning(Object result) {
        log.debug("【业务后置通知】执行返回值：{}", result);
    }

    @AfterThrowing(pointcut = "pointCutMethod()", throwing = "e")
    public void afterThrowing(Exception e) {
        log.debug("【业务后置通知】出现异常：{}", e.getMessage());
    }

    @After("pointCutMethod()")
    public void after() {
        log.debug("【业务后置通知】执行完成");
    }

}
